#include <iostream>
#include <iomanip>
#include <cstring>
#include <string>
#include <string.h>

#include <sys/socket.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#include "my_utils.h"

int initServer(in_addr_t addr, uint16_t port)
{
    int server_sock;
    struct sockaddr_in server_addr; // 使用结构体 SOCKADDR_IN 存储配置
    server_sock = socket(AF_INET, SOCK_STREAM, 0);

    memset(&server_addr, 0, sizeof(server_addr)); // 清零
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = addr; // server端ip地址
    server_addr.sin_port = port;      // 监听端口

    int res = bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));

    if (res < 0)
    {
        return -1;
    }
    return server_sock;
}

int main()
{
    // 初始化socket服务端
    uint16_t port = htons(9000);
    in_addr_t addr = inet_addr("127.0.0.1");

    int server = initServer(addr, port);

    struct sockaddr_in client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    int res = -1;
    int client_sock = -1;
    unsigned char buffer[1024];

    while (true)
    {
        // 监听连接
        if (res == -1)
        {
            std::cout << "server listen error" << std::endl;
            res = listen(server, 10);
            continue;
        }

        // 获取连接
        if (client_sock == -1)
        {
            std::cerr << "failed to accept socket" << std::endl;
            client_sock = accept(server, (struct sockaddr *)&client_addr, &client_addr_len);
            continue;
        }

        // 获取请求数据
        int read_size = recv(client_sock, buffer, sizeof(buffer), 0);
        if (read_size <= 0)
        {
            // 如果read_size小于0,说明出现了错误，此时应该关闭连接重新等待连接
            // 如果错误为EINTR是由中断引起的
            // 如果是ECONNREST表示网络连接出了问题
            close(client_sock);
            std::cerr << "client close connection" << std::endl;
            res = -1;
            client_sock = -1;
            continue;
        }
        std::cout << "accpet client: " << byte2String(buffer, 0, read_size) << std::endl;

        // 发送数据
        std::vector<unsigned char> request = string2Bytes("x=0,y=0,a=0,");
        unsigned char send_buf[request.size()];
        std::copy(request.begin(), request.end(), send_buf);
        send(client_sock, send_buf, request.size(), 0);
    }

    close(client_sock);
    close(server);
}